import LayerRenderStatus from "../types/LayerRenderStatus";
import { Plugin } from "../types/Plugin";
import { PdfJs } from "../interface";
import WithScale from "./WithScale";
import { FC, useRef } from "react";

import { renderTextLayer } from "pdfjs-dist";

interface TextLayerProps {
  page: PdfJs.Page;
  pageIndex: number;
  plugins: Plugin[];
  rotation: number;
  scale: number;
}

const TextLayer: FC<TextLayerProps> = ({
  page,
  pageIndex,
  plugins,
  rotation,
  scale,
}) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const renderTask = useRef<PdfJs.PageRenderTask>();

  const empty = (): void => {
    const containerEle = containerRef.current;
    if (!containerEle) {
      return;
    }
    const spans = containerEle.querySelectorAll(
      "span.rpv-core__text-layer-text"
    );
    const numSpans = spans.length;
    for (let i = 0; i < numSpans; i++) {
      const span = spans[i];
      containerEle.removeChild(span);
    }
  };

  const renderText = (): void => {
    const task = renderTask.current;
    if (task) {
      task.cancel();
    }

    const containerEle = containerRef.current;
    if (!containerEle) {
      return;
    }
    const viewport = page.getViewport({ rotation, scale });

    plugins.forEach((plugin) => {
      if (plugin.onTextLayerRender) {
        plugin.onTextLayerRender({
          ele: containerEle,
          pageIndex,
          scale,
          status: LayerRenderStatus.PreRender,
        });
      }
    });
    page.getTextContent().then((textContent) => {
      empty();
      renderTask.current = renderTextLayer({
        container: containerEle,
        textContent,
        viewport,
        enhanceTextSelection: true,
      });
      renderTask.current.promise.then(
        () => {
          const spans = containerEle.childNodes;
          const numSpans = spans.length;
          for (let i = 0; i < numSpans; i++) {
            const span = spans[i] as HTMLElement;
            span.classList.add("rpv-core__text-layer-text");
          }
          plugins.forEach((plugin) => {
            if (plugin.onTextLayerRender) {
              plugin.onTextLayerRender({
                ele: containerEle,
                pageIndex,
                scale,
                status: LayerRenderStatus.DidRender,
              });
            }
          });
        },
        () => {
          /**/
        }
      );
    });
  };

  return (
    <WithScale callback={renderText} rotation={rotation} scale={scale}>
      <div className="rpv-core__text-layer" ref={containerRef} />
    </WithScale>
  );
};

export default TextLayer;
